import 'dart:io';

import 'package:hive/hive.dart';
import 'package:path/path.dart' as path;
import 'package:get/get.dart';
import 'package:friends_flutter/config/net/api.dart';

import '../constants.dart';

class UploadService extends GetxService {
  static UploadService get to => Get.find<UploadService>();

  RxList<UploadTaskModel> uploadList = <UploadTaskModel>[].obs;

  @override
  void onInit() {

    Future.delayed(const Duration(seconds: 3), () {
      try {
        uploadList.value = Hive.box(Constants.hiveDatabase).values.map((e) => e as UploadTaskModel).toList().reversed.toList();
        print('uploadList.value = $uploadList');
      } catch (err) {
        print(' uploadList.value err = $err');
      }
    });

    super.onInit();
  }

  Future<void> addUploadTask(File file) async {
    UploadTaskModel uploadTaskModel = UploadTaskModel(name: path.basename(file.path), status: UploadTaskStatus.running, filePath: file.path);
    print('addUploadTask 111111111 ${uploadTaskModel.filePath}');
    if (!file.existsSync()) {
      print('该上传文件不存在');
      return ;
    }
    // Api.uploadFile(uploadTaskModel);
    uploadList.insert(0, uploadTaskModel);
  }

  // 从列表中删除一个上传项
  void removeUploadTask(UploadTaskModel uploadTaskModel) {
    uploadList.remove(uploadTaskModel);
  }

}

enum UploadTaskStatus {
  pending, //等待上传
  running, //上传中
  success, //上传成功
  fail;    //上传失败

  static enumToString(UploadTaskStatus uploadTaskStatus) {
    String result = '';
    switch (uploadTaskStatus) {
      case pending:
        result = '等待上传';
        break;
      case running:
        result = '上传中';
        break;
      case success:
        result = '上传成功';
        break;
      case fail:
        result = '上传失败';
        break;
    }
    return result;
  }
}

@HiveType(typeId: 0)
class UploadTaskModel {
  @HiveField(0)
  String name;

  @HiveField(1)
  String filePath;

  @HiveField(2)
  UploadTaskStatus status;

  @HiveField(3)
  final RxDouble progress = RxDouble(0.0);

  UploadTaskModel({required this.name, required this.filePath, required this.status});
}

class UploadTaskModelAdapter extends TypeAdapter<UploadTaskModel> {
  @override
  final int typeId = 0;

  @override
  UploadTaskModel read(BinaryReader reader) {
    final numOfFields = reader.readByte();
    final fields = <int, dynamic>{};
    for (var i = 0; i < numOfFields; i++) {
      final fieldIndex = reader.readByte();
      final fieldValue = reader.read();
      fields[fieldIndex] = fieldValue;
    }
    return UploadTaskModel(
      name: fields[0] as String,
      filePath: fields[1] as String,
      status: UploadTaskStatus.values[fields[2]],
    )..progress.value = fields[3] as double;
  }

  @override
  void write(BinaryWriter writer, UploadTaskModel obj) {
    writer.writeByte(4);
    writer.writeByte(0);
    writer.write(obj.name);
    writer.writeByte(1);
    writer.write(obj.filePath);
    writer.writeByte(2);
    writer.write(obj.status.index);
    writer.writeByte(3);
    writer.write(obj.progress.value);
  }

  @override
  int get hashCode => typeId.hashCode;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
          other is UploadTaskModelAdapter &&
              runtimeType == other.runtimeType &&
              typeId == other.typeId;
}

